# JSON libraries
library(rjson)
library(RJSONIO)
library(jsonlite)
# To read the netCDF file (check for better options!)
library(ncdf4)
# To get the min bounding box
library(sp)
library(shotGroups)
# To plot the track of the glider
library(spacetime)
library(trajectories)
library(leaflet)
# To format dates
library(lubridate)
# ?? Not sure why I was using this
library(tidyverse)
# to format text in the console (does not format text in R markdown)
require(crayon)
ListLoadedLibraries = function(){
# Listing the default libraries. These do not need to be listed
defaultLibraries = list("stats","graphics" ,"grDevices","utils","datasets" ,"methods","base")
# Listing the loaded libraries
loadedLibraries = (.packages())
# Getting the loaded libraries only
LoadedlibrariesOnly = setdiff(loadedLibraries, defaultLibraries)
# Adding package: to the names of the libraries
libraries1= paste0("package:", LoadedlibrariesOnly)
sapply(libraries1, ls)
}
The following function gets the time dimension from the glider netCDF file and converts it from double to Unix time. The fucnction also extracts the time stamp and the date as well. This function returns a dataframe that has the formatted time in addition the timestamp and the date. This function takes an ncdf4 object as an argument.
formatTimeDim <- function(file){
tryCatch(
expr = {
# Getting the time dimension
time = file$dim$TIME
# Formatting time
time_formatted = as.POSIXct(time$vals, origin="1970-01-01")
# Extracting the time stamp from the unix time object
timeStamp = format(time_formatted,'%H:%M:%S')
# Extracting the date from the unix time object
date = as.Date(time_formatted)
# Combining the formatted time, the time stamp and the date in one data frame
all = cbind.data.frame(time_formatted, timeStamp, date)
message('The time dimension has been successfully formatted!')
# returning the dataframe
return(all)
},
error = function(e){
message('Caught an error!')
print(e)
},
warning = function(w){
message('Caught an warning!')
print(w)
}
)
}
This function should return a dataframe that has the lat, lon, the time formatted, time stamp and date with no NA data.
combineLatLongWithTime <- function(filePath){
tryCatch(
expr = {
# Reading the file
file = nc_open(file_Path)
# Getting the latitude and longitude
lon = ncvar_get(file,"LONGITUDE")
lat = ncvar_get(file,"LATITUDE")
# Calling the time function to get the dataframe that has the time formatted
time = formatTimeDim(file)
# Combining the time data frame with lat and long. This dataframe has NA values
dataframe = cbind.data.frame(lat, lon, time)
cat(bold("The number of NA this file has is: ", sum(is.na(dataframe))))
cat("\n")
# removing NA values
dataframe_No_NA = dataframe %>% drop_na()
return(dataframe_No_NA)
message("dataframe successfully created!")
},
error = function(e){
message('Caught an error!')
print(e)
},
warning = function(w){
message('Caught an warning!')
print(w)
}
)
}
# This is where the netCDF data files reside
netCDF_Data_Files_Path = "D:/University/WWU/WWU 5/Task 1/Reading netCDF data using R/"
# This is the files that needs to be read
netCDF_File_Name = "wallis_mooset01_R.nc"
# This is the complete path to the netCDF file that is being read
file_Path = paste0(netCDF_Data_Files_Path,netCDF_File_Name)
lat_lon_time_No_NA = combineLatLongWithTime(file_Path)
## The time dimension has been successfully formatted!
## The number of NA this file has is: 464
# Converting the dataframe to a SpatialPoints object
lat_lon_spatial = SpatialPoints(lat_lon_time_No_NA %>% select(1:2))
# Applying the bbox function
bb_sp = bbox(lat_lon_spatial)
head(lat_lon_spatial)
## SpatialPoints:
## lat lon
## [1,] 43.00009 5.993153
## [2,] 43.00021 5.992803
## [3,] 43.00055 5.992498
## [4,] 43.00055 5.992292
## [5,] 43.00059 5.992281
## [6,] 43.00063 5.992271
## Coordinate Reference System (CRS) arguments: NA
bb_sp
## min max
## lat 41.674347 43.00926
## lon 5.399076 7.16478
This function also returns the width and height of the bounding box. Since the projection is WGS84. This information is not useful.
lat_lon = lat_lon_time_No_NA %>% select(1:2)
names(lat_lon)[1] = "point.x"
names(lat_lon)[2] = "point.y"
bb = getBoundingBox(lat_lon)
bb
## $pts
## xleft ybottom xright ytop
## 41.674347 5.399076 43.009263 7.164780
##
## $width
## [1] 1.334915
##
## $height
## [1] 1.765704
##
## $FoM
## [1] 1.55031
##
## $diag
## [1] 2.213529
I am not sure how to select the first tow colomns of the dataframe that has lat, lon, time…… is it better if I put lat,lon in a seperate dataframe???? It looks to me that lat_lon_time_No_NA %>% select(1:2) makes things more complicated!!!
# Setting a projection
crs = CRS("+proj=longlat +datum=WGS84")
# Creating an STIDF object
stidf = STIDF(SpatialPoints(lat_lon_time_No_NA %>% select(1:2),crs), lat_lon_time_No_NA$time_formatted, data.frame(lat_lon_time_No_NA %>% select(1:2)))
# Creating a track object
glider_track = Track(stidf)
plot(glider_track)
# Accessing the coordinates of the Track object
# A1@data[,1]
# A1@data[,2]
# Ploting the glider track using leflet
leaflet() %>%addTiles() %>% addPolylines(lat = glider_track@data[,1], lng = glider_track@data[,2])
What I thought of is splitting the dataframe that has all the days in the netCDF file into seperate dataframes each containing the measurement for each day. The first row of each dataframe is then extracted to get the first measurement of that day.
# Splitting the dataframe based on date
# This results in a list of dataframes
list = split(lat_lon_time_No_NA, lat_lon_time_No_NA$date)
#This provides the first row of each day in the data frame
first_days = do.call(rbind, (lapply(list, function(x) x[1,])))
# Plotting the glider track with labels
leaflet() %>%addTiles() %>% addPolylines(lat = glider_track@data[,1], lng = glider_track@data[,2]) %>% addAwesomeMarkers(data = first_days, lat = ~first_days$lat, lng = ~first_days$lon, label = first_days$time_formatted)
# !!! I tried this but it does not work !!!
# I wanted to get the minimum date of each day in the dataframe
# test %>% group_by(time_D_formatted) %>% filter(time_D_formatted == min(time_D_formatted))
# Accessing the coordinates of the Track object
# A1@data[,1]
# A1@data[,2]
# Ploting the glider track using leflet
# leaflet() %>%addTiles() %>% addPolylines(lat = glider_track@data[,1], lng = glider_track@data[,2])
This is not effecient at all and R crashed when I tried it.
#time_array = lat_lon_time_dateframe[,3]
#head(time_array)
#Getting the first value of the arry
#first_value = time_array[1]
#as.Date(ymd_hms(first_value))
#for(i in time_array){
# as.Date(ymd_hms(i))
#}
# Getting the last day
last_day_df = as.data.frame(tail(list, n = 1))
# Setting the name of the columns to the same names of the first_days dataframe
# This makes it easier to combine both dataframes
names(last_day_df) = colnames(first_days)
last_day = tail(last_day_df, n=1)
#Adding the last value of the last day to the first_days dataframe
first_days_plus_last_value = rbind(first_days, last_day)
# Plotting the glider track with labels including the last vlaue of the last day
leaflet() %>%addTiles() %>% addPolylines(lat = glider_track@data[,1], lng = glider_track@data[,2]) %>% addMarkers(data = first_days_plus_last_value, lat = ~first_days_plus_last_value$lat, lng = ~first_days_plus_last_value$lon, label = first_days_plus_last_value$time_D_formatted)
# This provides a summary of the dataframe based on the date
#lat_lon_time_dateframe %>% group_split(date) %>% map(summary)